﻿#nullable enable
namespace NServiceBus;

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Hosting;
using Microsoft.Extensions.DependencyInjection;

partial class HostingComponent
{
    public static Configuration PrepareConfiguration(Settings settings, List<Type> availableTypes,
        PersistenceComponent.Configuration persistenceConfiguration, InstallerComponent installerComponent,
        IServiceCollection serviceCollection)
    {
        var configuration = new Configuration(settings,
            availableTypes,
            new CriticalError(settings.CustomCriticalErrorAction),
            settings.StartupDiagnostics,
            settings.DiagnosticsPath,
            settings.HostDiagnosticsWriter,
            settings.EndpointName,
            serviceCollection,
            settings.ShouldRunInstallers,
            settings.UserRegistrations,
            settings.EnableOpenTelemetry ? new ActivityFactory() : new NoOpActivityFactory(),
            persistenceConfiguration,
            installerComponent);

        return configuration;
    }

    public class Configuration
    {
        public Configuration(Settings settings,
            List<Type> availableTypes,
            CriticalError criticalError,
            StartupDiagnosticEntries startupDiagnostics,
            string? diagnosticsPath,
            Func<string, CancellationToken, Task>? hostDiagnosticsWriter,
            string endpointName,
            IServiceCollection services,
            bool shouldRunInstallers,
            List<Action<IServiceCollection>> userRegistrations,
            IActivityFactory activityFactory,
            PersistenceComponent.Configuration persistenceConfiguration,
            InstallerComponent installerComponent)
        {
            AvailableTypes = availableTypes;
            CriticalError = criticalError;
            StartupDiagnostics = startupDiagnostics;
            DiagnosticsPath = diagnosticsPath;
            HostDiagnosticsWriter = hostDiagnosticsWriter;
            EndpointName = endpointName;
            Services = services;
            ShouldRunInstallers = shouldRunInstallers;
            UserRegistrations = userRegistrations;
            ActivityFactory = activityFactory;
            PersistenceConfiguration = persistenceConfiguration;
            InstallerComponent = installerComponent;

            settings.ApplyHostIdDefaultIfNeeded();
            HostInformation = new HostInformation(settings.HostId, settings.DisplayName, settings.Properties);
        }

        public ICollection<Type> AvailableTypes { get; }

        public CriticalError CriticalError { get; }

        public StartupDiagnosticEntries StartupDiagnostics { get; }

        public Func<string, CancellationToken, Task>? HostDiagnosticsWriter { get; }

        public string EndpointName { get; }

        public IServiceCollection Services { get; }

        public string? DiagnosticsPath { get; }

        public void AddStartupDiagnosticsSection(string sectionName, object section) => StartupDiagnostics.Add(sectionName, section);

        public HostInformation HostInformation { get; }

        public bool ShouldRunInstallers { get; }

        public List<Action<IServiceCollection>> UserRegistrations { get; }

        public IActivityFactory ActivityFactory { get; set; }

        public PersistenceComponent.Configuration PersistenceConfiguration { get; }
        public InstallerComponent InstallerComponent { get; }
    }
}